# 1 зад

Foo < Bar < Baz < Object

  case 3 of
      y: Int => y; 
      z: Bool => z;
  esac;
lub(Int, Bool) = Object

  if 0 = 1 then new Bar else new Foo fi;
lib(Bar, Foo) = Bar
Връща Bar, понеже Foo < Bar

  let x: Bazz ← new Bar in x;
Bazz

# 2 зад

Статична видимост, следователно
foo(z) <-> 5 + z
bar(y) <-> 5 + y

foo(bar(3)) <-> foo(8) <-> 13

# 3 зад

x = 7
  \ foo(bar(3))
        |
        x = 1, z = 2
          \ foo(3)
            |
            z = 3
              \ x + z <-> 1 + 3 <-> 4
  \ foo(4)
    |
    z = 4
      \ x + z <-> 7 + 4 <-> 11

# 4 зад

21   bar(): (*MISSING*) {
22     case foo() of
23       f: Foo => f@Foo.foo();
24       b: Bar => (new Bazz).foo();
25       o: Object => foo();
26     esac
27   };
lub(f@Foo.foo(), (new Bazz).foo(), foo())
f: Foo => SELF_TYPE = Foo, Foo.foo: Foo
Bazz.foo, SELF_TYPE = Bazz => Baz.foo: Bazz
(new Bar).foo => SELF_TYPE = Bar, foo: Bar

Bazz < Bar < Foo < IO < Object
lub(Foo, Bazz, Bar) \in { Foo, IO, Object } => a., d., e. са верни

# 5 зад

main -> (new Bar).bar() -> case foo() of ... -> foo() -> print "Bar.foo()"; return new Bar;
case new Bar of
  ...
  b: Bar => (new Bazz).foo() -> pinrt "Bazz.foo()"; (new Bar)@Foo.foo(); -> Foo.foo() -> print "Foo.foo()"; foo() -> Bar.foo() -> print "Bar.foo()"
